<template>
  <el-card class="box-card">
    <div class="check-app">
      <div class="select">
        <el-select
          v-model="currentApp"
          class="m-2"
          placeholder="请选择应用"
          style="width: 240px"
          :suffix-icon="CaretBottom"
          @change="changeApp"
        >
          <el-option
            v-for="item in appList"
            :key="item.id"
            :label="item.name"
            :value="item.id"
          />
        </el-select>
      </div>
      <div class="check-search">
        <el-button round type="primary" @click="addMenu('add', null)" style="margin-right: 10px;" :icon="Plus" v-if="getBtnPermission('btn:menuManage')">
        </el-button>
        <el-form @submit.native.prevent="() => getMenus">
          <el-form-item>
            <el-input placeholder="请输入菜单名称" v-model="menuKeyWord" @keyup.enter="getMenus">
              <template #suffix>
                <el-icon class="el-input__icon curP"  @click="getMenus"><Search /></el-icon>
              </template>
            </el-input>
          </el-form-item>
        </el-form>
      </div>
    </div>

    <div class="table-data" v-loading="loading" id="table-data">
      <el-table
        :data="menuData"
        row-key="id"
        show-overflow
        keep-source
        scrollbar-always-on
      >
        <el-table-column prop="actionName" label="菜单名称" min-width="150">
        </el-table-column>

        <el-table-column prop="type" label="菜单类型" min-width="150">
          <template #default="{ row }">
            <span>{{ row.type == '0' ? '菜单权限' : row.type == '1' ? '路由权限' : row.type == '2' ? '按钮权限' : ''}}</span>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" min-width="80">
          <template #default="{ row }">
            <span>{{ row.status == '0' ? '禁用' : row.status == '1' ? '启用' : ''}}</span>
          </template>
        </el-table-column>
        <el-table-column prop="description" label="备注" min-width="150" />

        <el-table-column prop="controlName" label="标识" min-width="150" />

        <el-table-column prop="address" label="操作" min-width="150" fixed="right">
          <template #default="{ row }">
            <el-button
              type="warning"
              link
              v-if="row.status == 1 && getBtnPermission('btn:menuManage')"
              @click="menuChange(row)"
              :disabled="buttonDisabled"
            >禁用</el-button>
            <el-button
              type="warning"
              link
              v-if="row.status == 0 && getBtnPermission('btn:menuManage')"
              @click="menuChange(row)"
              :disabled="buttonDisabled"
            >启用</el-button>
            <el-button
              link
              @click="addMenu('edit', row)"
              style="color: #5897DB;"
              :disabled="buttonDisabled"
              v-if="getBtnPermission('btn:menuManage')"
            >编辑</el-button>
            <el-button
              link
              @click="addMenuChild(row)"
              style="color: #5897DB;"
              :disabled="buttonDisabled"
              v-if="getBtnPermission('btn:menuManage')"
            >添加下级</el-button>
            <el-button
              link
              @click="menuDelete(row)"
              style="color: #5897DB;"
              :disabled="buttonDisabled"
              v-if="getBtnPermission('btn:menuManage')"
            >删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <el-dialog title="配置菜单" v-model="dialogVisible" draggable @close="cancelMenu">
      <el-form
        ref="ruleFormRef"
        :model="ruleForm"
        label-width="100px"
        class="demo-ruleForm"
        status-icon
        :rules="rules"
      >
        <el-form-item label="菜单名称" prop="actionName">
          <el-input v-model="ruleForm.actionName" placeholder="请输入菜单名称"></el-input>
        </el-form-item>

        <el-form-item label="权限类型" prop="type">
          <el-select v-model="ruleForm.type" placeholder="请选择权限类型" style="width: 100%;">
            <el-option label="菜单" :value="0" />
            <el-option label="路由" :value="1" />
            <el-option label="按钮" :value="2" />
          </el-select>
        </el-form-item>

        <el-form-item label="上级菜单" prop="parentId" v-if="isAddChild">
          <el-tree-select
            v-model="ruleForm.parentId"
            :data="menuData"
            check-strictly
            :render-after-expand="false"
            style="width: 100%;"
            :props="defaultProps"
          />
        </el-form-item>
        
        <el-form-item label="权限标识" prop="controlName" :rules="[{ required: ruleForm.type != 0, message: '请输入权限标识', trigger: 'change' }]">
          <el-input v-model="ruleForm.controlName" placeholder="请输入权限标识，路由示例：/xxx，按钮示例：btn:xxx"></el-input>
        </el-form-item>

        <el-form-item label="图标" prop="icon">
          <el-icon v-if="ruleForm.icon" style="font-size: 26px; margin-right: 12px;">
            <component :is="iconsData[ruleForm.icon]"></component>
          </el-icon>
          <el-button type="primary" @click="iconDialogVisible = true">点击选择图标</el-button>
        </el-form-item>

        <el-form-item label="备注" prop="description">
          <el-input v-model="ruleForm.description" placeholder="请输入备注"></el-input>
        </el-form-item>
      </el-form>
      <div class="dialog-button">
        <el-button @click="cancelMenu" :loading="menuButtonLoading">取消</el-button>
        <el-button type="primary" @click="submitMenu" :loading="menuButtonLoading">{{ isAdd == 'add' ? '添加' : '编辑' }}</el-button>
      </div>
    </el-dialog>

    <el-dialog title="选择图标" v-model="iconDialogVisible" draggable @close="cancelIcon" width="40%">
      <div class="icon-list">
        <li v-for="(name, index) in iconsData" :key="index" class="icon-item curP" :class="{ 'icon-active' : chooseIcon == name.name }" @click="checkIcon(name)">
          <el-icon style="font-size: 30px">
            <component :is="name"></component>
          </el-icon>
        </li>
      </div>
      <div class="dialog-button">
        <el-button type="primary" @click="submitIcon">确定</el-button>
      </div>
    </el-dialog>
  </el-card>
</template>

<script setup name="menu">

import { computed, onMounted, ref, reactive, toRefs, shallowRef  } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus'
import { http } from '@/utils/http/index';
import * as ElIcons from '@element-plus/icons-vue'
import { CaretBottom, Search, Plus, Aim } from '@element-plus/icons-vue'
import { useAuthStore } from '@/stores/modules/auth.js';

const authStore = useAuthStore()

/* 所有按钮权限 */
const btnPermissionList = ref([])
btnPermissionList.value = authStore.base_auth_tree.find(item => item.controlName == 'btn_permission')?.children

/* 查询是否有权限 */
const getBtnPermission = (name) => {
  let flag = false
  if( btnPermissionList.value.find(item => item.controlName == name && item.selected == 1) ) {
    flag = true
  }
  return flag
}

/* 当前所选应用 */
const currentApp = ref()
/* 切换当前应用 */
const changeApp = (val) => {
  currentApp.value = val
  menuKeyWord.value = ""
  menuData.value = []
  getMenusList()
}

/* 获取所有应用列表 */
const appList = ref([])
const getAppList = () => {
  http.$GET("/AppManager/GetAppList").then(res => {
    appList.value = res.result.content
    if( !res.result.content.length ) return
    currentApp.value = res.result.content[0].id
    getMenusList()
  })
}
getAppList()

/* 树表格数据 */
const menuData = ref([])
const loading = ref(false)
/* 获取菜单树 */
const getMenusList = () => {
  loading.value = true
  http.$GET("/Action/GetActionTreeByApplicationId?applicationId=" + currentApp.value).then(res => {
    loading.value = false
    if(res.isError) return ElMessage.warning("加载失败")
    if(!res.result.content) return menuData.value = []
    if(menuKeyWord.value) {
      let arr = handleTreeData(res.result.content, menuKeyWord.value)
      menuData.value = arr
    } else {
      menuData.value = res.result.content
    }
  })
}

/* 点击查询菜单 */
const menuKeyWord = ref("")
const getMenus = () => {
  if(menuKeyWord.value) {
    let arr = handleTreeData(menuData.value, menuKeyWord.value)
    menuData.value = arr
  }
}
/* 过滤树 */
const handleTreeData = (treeData, searchValue) => {
  if (!treeData || treeData.length === 0) {
    return [];
  }
  const array = [];
  for (let i = 0; i < treeData.length; i += 1) {
    let match = false;
    for(let pro in treeData[i]){
      if(typeof(treeData[i][pro])=='string'){
        match |= treeData[i][pro].includes(searchValue);
        if(match) break;
      }
    }
    if (handleTreeData(treeData[i].children, searchValue).length > 0 || match ) {
      array.push({
        ...treeData[i],
        children: handleTreeData(treeData[i].children, searchValue),
      });
    }
  }
  return array;
}

/* 操作列按钮禁用 */
const buttonDisabled = ref(false)

/* 点击新增、编辑菜单 */
const addMenu = (type, row) => {
  isAdd.value = type
  dialogVisible.value = true
  if(row) {
    if(row.parentId != "") {
      isAddChild.value = true
    } else {
      isAddChild.value = false
    }
    Object.keys(ruleForm.value).forEach((key)=>{
      if(row[key] != null){
        ruleForm.value[key] = row[key];
      }
    })
    ruleForm.value.id = row.id
  } else {
    isAddChild.value = false
    ruleForm.value.id = ""
    ruleForm.value.parentId = ""
  }
}

/* 点击添加子级菜单 */
const addMenuChild = (row) => {
  isAddChild.value = true
  dialogVisible.value = true
  isAdd.value = 'add'
  ruleForm.value.parentId = row.id
  ruleForm.value.id = ""
}

/* 点击删除菜单 */
const menuDelete = (row) => {
  ElMessageBox.confirm(
    '确定删除此权限配置吗？',
    '请确认',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  ).then(() => {
    buttonDisabled.value = true
    http.$POST("/Action/delActionById?id=" + row.id).then(res => {
      buttonDisabled.value = false
      if(res.isError) return ElMessage.warning(res.message)
      ElMessage.success("操作成功")
      getMenusList()
    })
  }).catch(() => {
    ElMessage.info("已取消删除")
  })
}

/* 点击更改菜单状态 */
const menuChange = (row) => {
  ElMessageBox.confirm(
    '确定更改此权限的状态吗？',
    '请确认',
    {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }
  ).then(() => {
    let params = {
      id: row.id,
      status: row.status == 0 ? 1 : 0
    }
    buttonDisabled.value = true
    http.$POST("/Action/ChangeStatusAction", params).then(res => {
      buttonDisabled.value = false
      if(res.isError) return ElMessage.warning(res.message)
      ElMessage.success("操作成功")
      getMenusList()
    })
  }).catch(() => {
    ElMessage.info("已取消变更")
  })
}

/* 添加菜单弹窗 */
const dialogVisible = ref(false)
const ruleForm = ref({
  type: '',
  actionName: '',
  parentId: '',
  controlName: '',
  description: '',
  icon: '',
})
const ruleFormRef = ref(null)
const isAdd = ref('add')
const isAddChild = ref(false)
const defaultProps = ref({
  children: 'children',
  label: 'actionName',
  value: "id"
})
const rules = ref({
  type: [
    { required: true, message: '请选择权限类型', trigger: 'change' }
  ],
  actionName: [
    { required: true, message: '请填写权限名称', trigger: 'blur' }
  ],
  parentId: [
    { required: true, message: '请选择上级菜单', trigger: 'change' },
  ],
  /* controlName: [
    { required: true, message: '请填写菜单路径', trigger: 'blur' },
  ], */
})

/* 取消添加 */
const cancelMenu = () => {
  ruleForm.value = {
    type: '',
    actionName: '',
    parentId: '',
    controlName: '',
    description: '',
    icon: '',
  }
  ruleFormRef.value.resetFields()
  dialogVisible.value = false
}

/* 点击添加 */
const menuButtonLoading = ref(false)
const submitMenu = () => {
  ruleFormRef.value.validate((valid, fields) => {
    if(valid) {
      menuButtonLoading.value = true
      let params = JSON.parse(JSON.stringify(ruleForm.value))
      params.actionGroupId = currentApp.value

      http.$POST("/Action/AddOrUpdateAction", params).then(res => {
        menuButtonLoading.value = false
        if(res.isError) return ElMessage.warning(res.message)
        ElMessage.success("操作成功")
        cancelMenu()
        getMenusList()
      }).catch(() => {
        menuButtonLoading.value = false
        cancelMenu()
        ElMessage.warning("操作失败")
      })
    } else {
      ElMessage.warning("请先完成必填项")
    }
  })
}

/* 选择图标 */
const iconDialogVisible = ref(false)
const chooseIcon = ref("")
const chooseIconName = ref("")
const checkIcon = (item) => {
  chooseIcon.value = item.name
}
const cancelIcon = () => {
  iconDialogVisible.value = false
  chooseIcon.value = ""
}
const submitIcon = () => {
  ruleForm.value.icon = chooseIcon.value
  cancelIcon()
}

/* 所有图标列表 */
const iconsData = ElIcons
</script>
<style lang='scss' scoped>
@import "@/assets/styles/backendElement.scss";

:deep(.table-data .el-table) {
  height: calc(100vh - 250px);
}
.check-app {
  padding: 15px 0;
  display: flex;
  justify-content: space-between;

  .select {

    :deep(.el-input__inner) {
      color: #2F3748;
      font-size: 16px;
      font-family: PingFang SC, PingFang SC;
      font-weight: 500;
      letter-spacing: 1px;
    }
  }

  .check-search {
    display: flex;
    :deep(.el-button.is-round){
      padding: 8px;
    }
  }
}

.icon-list {
  height: 400px;
  overflow: auto;
  padding: 1px 0 0 1px;
}
.icon-item {
  display: inline-block;
  border: 1px solid #ccc;
  border-collapse: collapse;
  padding: 12px;
  margin-left: -1px;
  margin-top: -1px;
}
.icon-active {
  background-color: #ccc;
}

:deep(.el-table__expand-icon) {
  .el-icon {
    font-size: 18px;
    vertical-align: text-bottom;
  }
}
</style>